package com.crazymakercircle.httpclient.conn;

import com.crazymakercircle.httpclient.ExpiredAddressResolverGroup;
import com.crazymakercircle.httpclient.NettyConfig;
import com.crazymakercircle.util.RemotingUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HttpConnectionFactory {
    private final EventLoopGroup group;
    private NettyConfig conf;
    private Bootstrap bootstrap;

    public HttpConnectionFactory(NettyConfig conf) {

        if (RemotingUtil.canUseEpoll()) {
            log.info(" 操作系统 使用epoll");
            this.group = new EpollEventLoopGroup(
                    conf.getIoThreads(),
//                Math.min(Runtime.getRuntime().availableProcessors(), 16),
                    new DefaultThreadFactory("netty-", true));

        } else {
            log.info("操作系统 使用 select ");
            this.group = new NioEventLoopGroup(
                    conf.getIoThreads(),
//                Math.min(Runtime.getRuntime().availableProcessors(), 16),
                    new DefaultThreadFactory("netty-", true));
        }


        this.conf = conf;
        createBootstrap();
    }

    private void createBootstrap() {
        bootstrap = new Bootstrap();
        bootstrap.group(group);
        bootstrap.resolver(new ExpiredAddressResolverGroup(conf.getDnsExpireTime()));
        bootstrap.option(ChannelOption.AUTO_READ, true);
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000);

         bootstrap.channel(RemotingUtil.canUseEpoll() ? EpollSocketChannel.class : NioSocketChannel.class);

        bootstrap.remoteAddress(conf.getRemoteAddress());
    }

    public HttpConnection createConnection() {
        return new HttpConnection(bootstrap.clone(), conf);
    }
}
